
//  Created by tucici on 2024/5/15.
//

import UIKit
import RealmSwift
import SwiftyJSON
class baseModel : Object , NSCopying{
    /// 名称
    @objc dynamic var name : String = ""
    /// 选中状态
    @objc dynamic var select : Bool = false
    /// 使用状态
    var enable : Bool {
        return !APP.pwd.isEmpty
    }
    fileprivate var _isEnable : Bool = true
    required override init() {}
    init(name:String){
        super.init()
        self.name = name
    }
    func copy(with zone: NSZone? = nil) -> Any {
        let copy = type(of: self).init()
        copy.name = "\(name)"
        copy.select = select
        copy._isEnable = _isEnable
        return copy
    }
    override class func ignoredProperties() -> [String] {
        return ["enable","_isEnable"]
    }
}


class CHModel : baseModel{
    override var enable: Bool {
        get { return super.enable == false ? super.enable : _isEnable}
        set {_isEnable = newValue}
    }
}




/// 滤波器类型
@objc enum FilterType : Int{
    ///Butterworth 滤波器：<具有平滑的频率响应特性，在通频带内具有尽可能平坦的幅度响应，在截止频率附近的过渡区具有最小的幅频响应变化率。>
    case butterW = 1
    ///Bessel 滤波器:  <是一种线性相位滤波器，其特点是在通频带内具有相对平滑的群延迟响应。>
    case bessel = 2
    /// linkR 滤波器：<允许信号在特定频率以上或以下通过，并以可调增益或削弱整个频谱。>
    case linkR = 0
    
    
    var value : String{
        switch self{
        case .bessel:
            return "Bessel"
        case .butterW:
            return "Butter-W"
        case .linkR:
            return "Link-R"
        }
    }
    static var arr_type : [FilterType] {
        return [.bessel, .butterW, .linkR]
    }
}



//MARK: - 滤波器模块
/// 滤波器模块
class FilterModule : CHModel{
    /// 滤波器类型
    dynamic var type : FilterType = .bessel
    ///直通 (Bypass)：<绕过意味着将信号直接传递，而不经过滤波器的处理。这通常用于在需要时将信号绕过滤波器，以允许信号在不进行任何滤波处理的情况下直接通过。>
    @objc dynamic var bypass : Bool = false
    ///Slope：表示滤波器的斜率，即频率响应曲线在截止频率之后的变化速率。<dB/oct：表示每倍频程（octave）内的衰减量，以分贝（dB）为单位。>
    @objc dynamic var slope : Int8 = 12
    ///截止频率
    @objc dynamic var cutFrency : Int = 0
    
    var oct_type : Int{
        switch type {
        case .butterW:
            switch slope{
            case 6:
                return 0
            case 12:
                return 6
            case 18:
                return 7
            case 24:
                return 8
            case 36:
                return 9
            case 48:
                return 10
            default:
                return -1
            }
        case .bessel:
            switch slope{
            case 6:
                return 0
            case 12:
                return 11
            case 18:
                return 12
            case 24:
                return 13
            case 36:
                return 14
            case 48:
                return 10
            default:
                return -1
            }
        case .linkR:
            switch slope{
            case 6:
                return 0
            case 12:
                return 1
            case 18:
                return 2
            case 24:
                return 3
            case 36:
                return 4
            case 48:
                return 5
            default:
                return -1
            }
        }
    }
    
    override static func ignoredProperties() -> [String] {
        return ["oct_type", "select"]
    }
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! FilterModule
        copy.type = type
        copy.bypass = bypass
        copy.slope = slope
        copy.cutFrency = cutFrency
        return copy
    }
}



//MARK: - 信号模块
/// 信号模块
class SignModule : CHModel{
    /// 频率
    @objc dynamic var frency : Int = 0
    /// 增益
    @objc dynamic var gain : Float = 0.0
    /// 分贝
    @objc dynamic var dB : Float = 0.0
    ///在DSP和滤波器设计中，“Q”因数（品质因数）是描述谐振系统或滤波器带宽与中心频率关系的关键参数。高 Q 因数表示滤波器频率选择性高，而低 Q 因数表示频率选择性低。理解和应用 Q 因数对于设计高效的滤波器和谐振系统至关重要。
    @objc dynamic var quality : Float = 7.2
    
    init(frency:Int) {
        super.init()
        self.name = "\(frency)"
        self.frency = frency
    }
    
    required init() {
        super.init()
    }
    override static func ignoredProperties() -> [String] {
        return ["select"]
    }
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! SignModule
        copy.frency = frency
        copy.gain = gain
        copy.dB = dB
        copy.quality = quality
        return copy
    }
}



//MARK: - 通道基类模型
/// 通道基类模型
class ChannelModel : CHModel {
    /// 通道号
    @objc dynamic var num:Int = 0
    /// 延迟的时间
    @objc dynamic var delay : Float = 0.0
    ///延迟模式 1 = ms  , 2 = cm ,  3 = in
    @objc dynamic var delayType = 1
    /// 静音
    @objc dynamic var mute : Bool = false
    ///相位 true = 180， false  = 0
    @objc dynamic var phase : Bool = false
    ///最大音量
    @objc dynamic var maxVolume : Int16 = 0
    ///最小音量
    @objc dynamic var minVolume : Int16 = -50
    ///当前音量
    @objc dynamic var Volume : Int16 = 0
    ///信号数组
    var signArray = List<SignModule>()
    
    ///当前选中状态的信号
    var selectSign : SignModule {
        return signArray.first(where: { $0.select }) ?? SignModule(frency: 0)
    }
    ///高通滤波器 (High-pass Filter)：<高通滤波器允许高于某个特定频率的信号通过，而阻止低于该频率的信号通过。这种滤波器通常用于去除低频噪声或限制信号的带宽。>
    @objc dynamic var highPass : FilterModule! = FilterModule()
    ///低通滤波器 (Low-pass Filter)：<低通滤波器允许低于某个特定频率的信号通过，而阻止高于该频率的信号通过。这种滤波器通常用于去除高频噪声或限制信号的带宽。>
    @objc dynamic var lowPass : FilterModule! = FilterModule()
    
    class func json<T: ChannelModel>(_ json: JSON) -> T {
        let s = T()
        guard let keys = json.dictionary?.keys else{return s}
        if keys.contains("select"){  s.select = json["select"].boolValue}
        if keys.contains("enable"){  s.enable = json["enable"].boolValue}
        if keys.contains("delay"){   s.delay = Float(json["delay"].floatValue)}
        if keys.contains("name"){
            s.name = json["name"].stringValue
            s.num = Int("\(s.name.last ?? "0")") ?? 0
        }
        
        return s
    }
    // 添加 required 初始化方法
    required init() {
        super.init()
        highPass.cutFrency = 20
        lowPass.cutFrency = 20000
    }
    override init(name:String){
        super.init(name: name)
        highPass.cutFrency = 20
        lowPass.cutFrency = 20000
        num = Int("\(name.last ?? "0")") ?? 0
    }
    
    override static func ignoredProperties() -> [String] {
        return ["selectSign","select"]
    }
    override class func primaryKey() -> String? {
        return "num"
    }
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! ChannelModel
        copy.num = num
        copy.delay = delay
        copy.delayType = delayType
        copy.mute = mute
        copy.phase = phase
        copy.maxVolume = maxVolume
        copy.minVolume = minVolume
        copy.Volume = Volume
        let copiedSignArray = List<SignModule>()
        for sign in signArray {
            copiedSignArray.append(sign.copy() as! SignModule)
        }
        copy.signArray = copiedSignArray
        copy.highPass = highPass?.copy() as? FilterModule
        copy.lowPass = lowPass?.copy() as? FilterModule
        return copy
    }
    
    func initSignArr(){
        let array = [20, 25, 32, 40, 50, 63, 80, 100,
                     125, 160, 200, 250, 315, 400, 500, 630,
                     800, 1000, 1250, 1600, 2000, 2500, 3150, 4000,
                     5000, 6300, 8000, 10000, 12500, 16000, 20000]
        let list = List<SignModule>()
        for freq in array {
            let signModule = SignModule(frency: freq)
            list.append(signModule)
        }
        signArray = list
    }
    
}



//MARK: - 输入通道
/// 输入通道
class InputModel : ChannelModel{
    /// 输出的目标通道
    @objc dynamic var targetName = ""
    
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! InputModel
        copy.targetName = targetName
        return copy
    }
}



//MARK: - 输出通道
/// 输出通道
class OutputModel: ChannelModel {
    /// assign输入通道数组
    private var inputArr_assign : List<String>{
        let array = Array(repeating: "", count: 8)
        let list = List<String>()
        for str in array {
            list.append(str)
        }
        list[num-1] = "\(num)"
        return list
    }
    
    /// assign输入通道数组
    var inputArr_custom = List<String>()
    /// 当前使用的输入通道数组
    var inputArr : List<String>{
        return APP.CHM.inputSelectType == 1 ? inputArr_assign : inputArr_custom
    }
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! OutputModel
        let copyArr = List<String>()
        for str in inputArr_custom {
            copyArr.append(str.copy() as! String)
        }
        copy.inputArr_custom = copyArr
        return copy
    }
    
    func initInputArr(){
        let array = Array(repeating: "", count: 8)
        let list = List<String>()
        for input in array {
            list.append(input)
        }
        inputArr_custom = list
    }
}



//MARK: - GroupModel
/// GroupModel
class GroupModel : CHModel {
    @objc dynamic var num : Int = 0
    override var select: Bool{
        didSet{
            for ch in chArr{
                ch.select = select
            }
        }
    }
    
    ///通道数组
    var chArr : [ChannelModel]! = [ChannelModel]()
    ///group中被优先选择的通道
    @objc dynamic var ch1 : ChannelModel! = ChannelModel()
    
    init(array:[ChannelModel], num:Int){
        super.init()
        self.chArr = array
        self.num = num
        var name = self.chArr.map{String(format: "%d&", $0.num)}.joined()
        name.removeLast()
        self.name = "Grouping\nCH"+name
    }
    
    override init(name:String){
        super.init(name: name)
    }
    
    // 添加 required 初始化方法
    required init() {
        super.init()
    }
    
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! GroupModel
        copy.select = select
        copy.ch1 = ch1.copy() as? ChannelModel
        copy.chArr = chArr.map{$0.copy() as! ChannelModel}
        return copy
    }
    
    func contain(ch:ChannelModel)->Bool{
        return chArr.contains(where: {$0.num == ch.num})
    }
}



//MARK: - 通道管理
/// 通道全局管理
class ChannelManager : baseModel{
    ///持有的通道
    @objc dynamic var ch1 : ChannelModel! = ChannelModel(name:"CH1")
    @objc dynamic var ch2 : ChannelModel! = ChannelModel(name:"CH2")
    @objc dynamic var ch3 : ChannelModel! = ChannelModel(name:"CH3")
    @objc dynamic var ch4 : ChannelModel! = ChannelModel(name:"CH4")
    @objc dynamic var ch5 : ChannelModel! = ChannelModel(name:"CH5")
    @objc dynamic var ch6 : ChannelModel! = ChannelModel(name:"CH6")
    @objc dynamic var ch7 : ChannelModel! = ChannelModel(name:"CH7")
    @objc dynamic var ch8 : ChannelModel! = ChannelModel(name:"CH8")
    var array : [ChannelModel] { return [ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8]}
    var select_ch : ChannelModel{
        return array.filter{$0.select}.first ?? default_ch
    }
    private lazy var default_ch : ChannelModel = {
       return array.first?.copy() as! ChannelModel
    }()
    ///持有的输出通道
    @objc dynamic var out_ch1 : OutputModel! = OutputModel(name:"CH1")
    @objc dynamic var out_ch2 : OutputModel! = OutputModel(name:"CH2")
    @objc dynamic var out_ch3 : OutputModel! = OutputModel(name:"CH3")
    @objc dynamic var out_ch4 : OutputModel! = OutputModel(name:"CH4")
    @objc dynamic var out_ch5 : OutputModel! = OutputModel(name:"CH5")
    @objc dynamic var out_ch6 : OutputModel! = OutputModel(name:"CH6")
    @objc dynamic var out_ch7 : OutputModel! = OutputModel(name:"CH7")
    @objc dynamic var out_ch8 : OutputModel! = OutputModel(name:"CH8")
    var out_array : [OutputModel] { return [out_ch1,out_ch2,out_ch3,out_ch4,out_ch5,out_ch6,out_ch7,out_ch8]}
    
    @objc dynamic var date:String = ""
    @objc dynamic var pwd:String = ""
    @objc dynamic var volume : Int = 0
    @objc dynamic var mute : Bool = false
    ///首页，InputSelect模式  Assign=1，Custom=2
    @objc dynamic var inputSelectType = 0
    @objc dynamic var data : String {
        var str = ""
        ///通道频率、Q值、增益
        for ch in array{
            for i in 0..<ch.signArray.count{
                str += BLEData.EQ([ch], i, ch.signArray[i]).data.hex+"|"
            }
        }
        
        ///分频器(高频，低频)
        for ch in array{
            str += BLEData.crossOver(ch, true).data.hex+"|"
            str += BLEData.crossOver(ch, false).data.hex+"|"
        }
        
        ///通道是/否静音， 正/反相
        for ch in array{
            str += BLEData.mute(ch).data.hex+"|"
            str += BLEData.phase(ch).data.hex+"|"
        }
        
        ///通道延时
        for ch in array{
            str += BLEData.delay(ch).data.hex+"|"
        }
        
        ///总音量
        str += BLEData.allMute(mute, Float(volume)).data.hex+"|"
        
        ///混音
        for out_ch in out_array{
            str += BLEData.sum(out_ch).data.hex+"|"
        }
        return str.replacingOccurrences(of: ", ", with: "")
    }
    
    var isLock:Bool {
        return !pwd.isEmpty
    }
    
    override static func ignoredProperties() -> [String] {
        return ["array","select_ch","isLock","default_ch"]
    }
    override class func primaryKey() -> String? {
        return "name"
    }
    override func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! ChannelManager
        copy.ch1 = ch1.copy() as? ChannelModel
        copy.ch2 = ch2.copy() as? ChannelModel
        copy.ch3 = ch3.copy() as? ChannelModel
        copy.ch4 = ch4.copy() as? ChannelModel
        copy.ch5 = ch5.copy() as? ChannelModel
        copy.ch6 = ch6.copy() as? ChannelModel
        copy.ch7 = ch7.copy() as? ChannelModel
        copy.ch8 = ch8.copy() as? ChannelModel
        
        copy.out_ch1 = out_ch1.copy() as? OutputModel
        copy.out_ch2 = out_ch2.copy() as? OutputModel
        copy.out_ch3 = out_ch3.copy() as? OutputModel
        copy.out_ch4 = out_ch4.copy() as? OutputModel
        copy.out_ch5 = out_ch5.copy() as? OutputModel
        copy.out_ch6 = out_ch6.copy() as? OutputModel
        copy.out_ch7 = out_ch7.copy() as? OutputModel
        copy.out_ch8 = out_ch8.copy() as? OutputModel
        copy.date = date
        copy.pwd = pwd
        copy.volume = volume
        copy.mute = mute
        copy.inputSelectType = inputSelectType
        return copy
    }
    // 添加 required 初始化方法
    required init() {
        super.init()
    }
}

